package edu.pku.sei.autounit.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import edu.pku.sei.autounit.reflect.Class;
import edu.pku.sei.autounit.reflect.Method;
import edu.pku.sei.autounit.reflect.java.TypeFactory;
import edu.pku.sei.autounit.util.NameFactory;
import edu.pku.sei.autounit.util.Statements;

public class JUnitGenerator {
	private List<TestCase> testCases;

	private String className;
	private String packageName;
	
	public JUnitGenerator(Class c,String packageName,String className){

		this.testCases = new ArrayList<TestCase>();
		this.packageName = packageName;
		this.className = className;
		NameFactory nf = new NameFactory();
		VariableFactory vf = new VariableFactory();
		for(Method m:c.getTestMethods()){
			testCases.add(new TestCase(
					nf.getName(m.getName(),NameFactory.TESTCASE),m,vf));
		}
	}
	
	public JUnitGenerator(java.lang.Class<?> clas){

		this.testCases = new ArrayList<TestCase>();
		this.packageName = clas.getPackage().getName();
		this.className = "Test"+clas.getSimpleName();
		TypeFactory tf = new TypeFactory();
		Class c = (Class) tf.getType(clas, null);
		NameFactory nf = new NameFactory();
		VariableFactory vf = new VariableFactory();
		for(Method m:c.getPublicMethods()){
			testCases.add(new TestCase(
					nf.getName(m.getName(),NameFactory.TESTCASE),m,vf));
		}
	}
	
	public Statements getCode(){

		Map<String,String> map = new HashMap<String, String>();
		map.put(className, packageName+"."+className);
		Statements head = new Statements();
		head.insertStatement("package "+packageName+";");
		head.insertStatement("import static org.junit.Assert.*;");
		head.insertStatement("import org.junit.Test;");
		
		Statements body = new Statements();
		
		body.insertStatement("public class "+className+"{");
		
		for(TestCase c:testCases){
			body.merge(c.getCode(map));
		}
		body.insertStatement("}");
		
		for(String s:map.values())
			head.insertStatement("import "+s+";");
		
		head.merge(body);
		return head;
	}
}
